#include <algorithm>

#include "ai_player.hpp"
#include "foreach.hpp"
#include "human_player.hpp"
#include "player.hpp"
#include "unit.hpp"
#include "wml_node.hpp"
#include "wml_utils.hpp"

namespace game {

player_ptr player::read(wml::const_node_ptr node)
{
	if(node->attr("type") == "human") {
		return player_ptr(new human_player(node));
	} else if(node->attr("type") == "ai") {
		return player_ptr(new ai_player(node));
	} else {
		return player_ptr();
	}
}

player::player(wml::const_node_ptr node)
  : id_(node->attr("id")), team_(node->attr("team")), color_index_(wml::get_int(node, "color"))
{
	FOREACH_WML_CHILD(unit_node, node, "commander") {
		commanders_.push_back(commander_unit_ptr(new commander_unit(*this, unit_node)));
	}

	FOREACH_WML_CHILD(loc_node, node, "starting_location") {
		starting_locs_.push_back(hex::location(wml::get_int(loc_node, "x"), wml::get_int(loc_node, "y")));
	}
}

player::~player()
{
}

bool player::is_hostile(const player& p) const {
	return team_ != p.team_;
}

void player::remove_dead_commanders()
{
	foreach(commander_unit_ptr& commander, commanders_) {
		if(commander->destroyed()) {
			commander = commander_unit_ptr();
		}
	}

	commanders_.erase(std::remove(commanders_.begin(), commanders_.end(), commander_unit_ptr()), commanders_.end());
}

void player::start_scenario()
{
}

void player::add_commander(commander_unit_ptr cmd)
{
	commanders_.push_back(cmd);
	cmd->set_owner(*this);
}

variant player::get_value(const std::string& key) const
{
	if(key == "id") {
		return variant(id_);
	} else if(key == "num_commanders") {
		int result = 0;
		foreach(const_commander_unit_ptr cmd, commanders_) {
			if(cmd && !cmd->destroyed()) {
				++result;
			}
		}
		return variant(result);
	} else if(key == "commanders") {
		std::vector<variant> v;
		foreach(commander_unit_ptr cmd, commanders_) {
			if(cmd && !cmd->destroyed()) {
				v.push_back(variant(cmd.get()));
			}
		}

		return variant(&v);
	}

	return variant();
}

void player::set_value(const std::string& key, const variant& value)
{
	if(key == "commanders") {
		std::vector<commander_unit_ptr> commanders;
		for(int n = 0; n != value.num_elements(); ++n) {
			commander_unit_ptr cmd(value[n].try_convert<commander_unit>());
			if(cmd) {
				commanders.push_back(cmd);
			}
		}

		commanders_ = commanders;
	}
}

}
